// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FPDFAPI_PARSER_CPDF_REFERENCE_H_
#define CORE_FPDFAPI_PARSER_CPDF_REFERENCE_H_

#include <set>

#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"

class CPDF_IndirectObjectHolder;

class CPDF_Reference final : public CPDF_Object {
 public:
  CONSTRUCT_VIA_MAKE_RETAIN;

  // CPDF_Object:
  Type GetType() const override;
  RetainPtr<CPDF_Object> Clone() const override;
  ByteString GetString() const override;
  float GetNumber() const override;
  int GetInteger() const override;
  CPDF_Reference* AsMutableReference() override;
  bool WriteTo(IFX_ArchiveStream* archive,
               const CPDF_Encryptor* encryptor) const override;
  RetainPtr<CPDF_Reference> MakeReference(
      CPDF_IndirectObjectHolder* holder) const override;

  uint32_t GetRefObjNum() const { return m_RefObjNum; }
  bool HasIndirectObjectHolder() const { return !!m_pObjList; }
  void SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum);

 private:
  friend class CPDF_Dictionary;

  CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum);
  ~CPDF_Reference() override;

  const CPDF_Object* GetDirectInternal() const override;
  const CPDF_Dictionary* GetDictInternal() const override;
  RetainPtr<CPDF_Object> CloneNonCyclic(
      bool bDirect,
      std::set<const CPDF_Object*>* pVisited) const override;

  const CPDF_Object* FastGetDirect() const;

  UnownedPtr<CPDF_IndirectObjectHolder> m_pObjList;
  uint32_t m_RefObjNum;
};

inline CPDF_Reference* ToReference(CPDF_Object* obj) {
  return obj ? obj->AsMutableReference() : nullptr;
}

inline const CPDF_Reference* ToReference(const CPDF_Object* obj) {
  return obj ? obj->AsReference() : nullptr;
}

inline RetainPtr<CPDF_Reference> ToReference(RetainPtr<CPDF_Object> obj) {
  return RetainPtr<CPDF_Reference>(ToReference(obj.Get()));
}

inline RetainPtr<const CPDF_Reference> ToReference(
    RetainPtr<const CPDF_Object> obj) {
  return RetainPtr<const CPDF_Reference>(ToReference(obj.Get()));
}

#endif  // CORE_FPDFAPI_PARSER_CPDF_REFERENCE_H_
`CPDF_Reference` 类表示一个对间接对象的引用，以下是这个类提供的接口功能：

### 类 `CPDF_Reference`

#### 构造函数与析构函数
1. * *CPDF_Reference(CPDF_IndirectObjectHolder * pDoc, uint32_t objnum) * *:
-使用间接对象持有者和对象号构造 `CPDF_Reference` 对象。

2. * *~CPDF_Reference() * *:
-析构函数，用于销毁 `CPDF_Reference` 实例。

#### CPDF_Object 的重载方法
3. * *Type GetType() const override * *:
-获取对象类型。

4. * *RetainPtr<CPDF_Object> Clone() const override * *:
  -克隆 `CPDF_Reference` 对象。

  5. * *ByteString GetString() const override * *:
-获取字符串表示。

6. * *float GetNumber() const override * *:
  -获取浮点型表示。

  7. * *int GetInteger() const override * *:
  -获取整数表示。

  8. * *CPDF_Reference * AsMutableReference() override * *:
  -获取可变的 `CPDF_Reference` 指针。

  9. * *bool WriteTo(IFX_ArchiveStream * archive, const CPDF_Encryptor * encryptor) const override * *:
-将引用对象写入到流中，并可能使用加密器。

10. * *RetainPtr<CPDF_Reference> MakeReference(CPDF_IndirectObjectHolder * holder) const override * *:
  -创建一个新的引用对象。

  #### 其他方法
  11. * *uint32_t GetRefObjNum() const** :
  -获取引用对象的对象号。

  12. * *bool HasIndirectObjectHolder() const** :
  -检查是否有间接对象持有者。

  13. * *void SetRef(CPDF_IndirectObjectHolder * pDoc, uint32_t objnum) * *:
  -设置引用的文档和对象号。

  #### 内部保护方法
  14. * *const CPDF_Object * GetDirectInternal() const override * *:
  -获取直接对象的内部实现。

  15. * *const CPDF_Dictionary * GetDictInternal() const override * *:
  -获取字典对象的内部实现。

  16. * *RetainPtr<CPDF_Object> CloneNonCyclic(bool bDirect, std::set<const CPDF_Object*>*pVisited) const override * *:
  -克隆非循环对象。

  17. * *const CPDF_Object * FastGetDirect() const** :
  -快速获取直接对象。

  #### 实用函数
  18. * *ToReference(CPDF_Object * obj) * *:
  -将 `CPDF_Object` 转换为 `CPDF_Reference` 指针，若对象为 `nullptr` 返回 `nullptr`。

  19. * *ToReference(const CPDF_Object * obj) * *:
-将常量 `CPDF_Object` 转换为常量 `CPDF_Reference` 指针，若对象为 `nullptr` 返回 `nullptr`。

20. * *ToReference(RetainPtr<CPDF_Object> obj) * *:
-将智能指针 `CPDF_Object` 转换为 `CPDF_Reference` 的智能指针。

21. * *ToReference(RetainPtr<const CPDF_Object> obj) * *:
-将常量智能指针 `CPDF_Object` 转换为常量 `CPDF_Reference` 的智能指针。

这些接口提供了对 PDF 中间接对象的引用和操作的支持，包括引用的构建、类型检查、克隆、获取对象号和直接对象等功能。